package core

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
	"github.com/ngaut/log"
	"strings"
	"time"
)

const (
	CONFIG_FILE = ""
)

type accountConfig struct {
	Key 		string 		`toml:"key"`
}

type redisConfig struct {
	Host string `toml:"host"`
	Port int    `toml:"port"`
	DB   int    `toml:"db"`
	Auth string `toml:"auth"`
}

func (r redisConfig) redisPool() *redis.Pool {
	return &redis.Pool{
		MaxIdle:     50,
		IdleTimeout: 240 * time.Second,
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", fmt.Sprintf("%s:%d", r.Host, r.Port), redis.DialDatabase(r.DB))
			if err != nil {
				return nil, err
			}
			if r.Auth != "" {
				if _, err := c.Do("AUTH", r.Auth); err != nil {
					c.Close()
					return nil, err
				}
			}
			return c, err
		},

		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			if time.Since(t) < 5*time.Second {
				return nil
			}
			_, err := c.Do("PING")
			return err
		},
	}
}

type logConfig struct {
	On     bool   `toml:"log_on"`
	Dir    string `toml:"log_dir"`
	File   string `toml:"log_file"`
	Level  string `toml:"log_level"`
	Rotate string `toml:"log_rotate"`
}

// 获取文件名
func (l logConfig) getFilePath() string {
	path := strings.TrimRight(l.Dir, "/")
	file := l.File
	if file == "" {
		file = "micro.log"
	}
	return fmt.Sprintf("%s/%s", path, file)
}

func (l logConfig) Setting() {
	filePath := l.getFilePath()
	if l.On && filePath != "" {
		log.SetOutputByName(filePath)
		log.SetLevelByString(l.Level)
		if l.Rotate == "H" || l.Rotate == "" {
			log.SetRotateByHour()
		} else {
			log.SetRotateByDay()
		}
		log.SetHighlighting(false)
	}
}

// database configs
type dbConfig struct {
	Host     string `toml:"host"`
	Port     int    `toml:"port"`
	Username string `toml:"username"`
	Password string `toml:"password"`
	DBName   string `toml:"dbname"`
	LogOn 	 bool 	`toml:"log_on"`
	LogDir 	 string `toml:"log_dir"`
}

func (config dbConfig) FormatDBConnection() string {
	return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True",
		config.Username, config.Password, config.Host, config.Port, config.DBName)
}

func (config dbConfig) GetDBLogConfig() (bool, string) {
	var dir string
	if config.LogDir == "" || config.LogDir == "/" {
		dir = "log"
	} else {
		dir = config.LogDir
	}
	return config.LogOn, strings.TrimRight(dir, "/") + "/sql.log"
}

type Configuration struct {
	App   		appConfig 						`toml:"app"`
	Accounts  	map[string]accountConfig        `toml:"account"`
	Log   		map[string]logConfig            `toml:"log"`
	Redis 		map[string]redisConfig 			`toml:"redis"`
	Db    		map[string]dbConfig    			`toml:"db"`
}

type appConfig struct {
	Name 			string 			`toml:"name"`
	Debug 			bool			`toml:"debug"`
	AppUrl 			string 			`toml:"app_url"`
	ImgUrl 			string 			`toml:"img_url"`
}

func newConfiguration() Configuration {
	return Configuration{
		Redis: 		make(map[string]redisConfig),
		Db:    		make(map[string]dbConfig),
		Accounts:	make(map[string]accountConfig),
	}
}
